home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / fsmake / RCS / disklabel.c,v < prev    next >
Encoding:
Text File  |  1992-11-05  |  18.5 KB  |  669 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    shirriff:1.2; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     90.10.10.16.00.33;  author rab;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     90.09.12.09.41.42;  author rab;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @@
  22.  
  23.  
  24. 1.2
  25. log
  26. @Made changes so that fsmake will compile and run under unix.
  27. Added an option to allow alternative spritehosts file.
  28. Added static declarations.
  29. @
  30. text
  31. @/* 
  32.  * disklabel.c --
  33.  *
  34.  *    Contains routines for modifying a disk's label..
  35.  *
  36.  * Copyright 1990 Regents of the University of California
  37.  * Permission to use, copy, modify, and distribute this
  38.  * software and its documentation for any purpose and without
  39.  * fee is hereby granted, provided that the above copyright
  40.  * notice appear in all copies.  The University of California
  41.  * makes no representations about the suitability of this
  42.  * software for any purpose.  It is provided "as is" without
  43.  * express or implied warranty.
  44.  */
  45.  
  46. #ifndef lint
  47. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/disklabel.c,v 1.1 90/09/12 09:41:42 rab Exp Locker: rab $ SPRITE (Berkeley)";
  48. #endif /* not lint */
  49.  
  50. #include "fsmake.h"
  51.  
  52. /*
  53.  * The 8 partitions, a through h.
  54.  */
  55. #define    A_PART    0
  56. #define B_PART    1
  57. #define C_PART    2
  58. #define D_PART    3
  59. #define E_PART    4
  60. #define F_PART    5
  61. #define G_PART    6
  62. #define H_PART    7
  63.  
  64. static ReturnStatus ScanDisktab();
  65.  
  66.  
  67. /*
  68.  *----------------------------------------------------------------------
  69.  *
  70.  * Reconfig --
  71.  *
  72.  *    Changes the configuration information of the disk. In
  73.  *    particular, the number of heads, sectors per track, and
  74.  *    cylinders may be changed.  If the "disktab" parameter is
  75.  *    true then the information is read from the disktab file.
  76.  *    Otherwise the disk is probed for its size and a
  77.  *    configuration is created that minimizes the amount of
  78.  *    wasted disk space.
  79.  *
  80.  * Results:
  81.  *    SUCCESS if the label was changed properly, FAILURE otherwise
  82.  *
  83.  * Side effects:
  84.  *    The disk configuration info in the label may be changed.
  85.  *    If it is changed then the partition map is zeroed.
  86.  *
  87.  *----------------------------------------------------------------------
  88.  */
  89.  
  90. ReturnStatus
  91. Reconfig(fid, disktab, disktabName, diskType, labelType, scsiDisk, labelPtrPtr)
  92.     int            fid;        /* Handle for first partition of disk*/
  93.     Boolean        disktab;    /* TRUE => use disktab file. */
  94.     char        *disktabName;    /* Name of disktab file. */
  95.     char        *diskType;    /* Type of disk. */
  96.     Disk_NativeLabelType labelType;    /* Type of label to write. */
  97.     int            scsiDisk;    /* TRUE => it's a scsi disk. */
  98.     Disk_Label        **labelPtrPtr;    /* Place to return label ptr. */
  99. {
  100.     Disk_Label        *labelPtr;
  101.     ReturnStatus    status = SUCCESS;
  102.     labelPtr = *labelPtrPtr;
  103.     if (labelPtr == NULL) {
  104.     labelPtr = Disk_ReadLabel(fid);
  105.     if (labelPtr != NULL) {
  106.         if ((labelType != DISK_NO_LABEL) && 
  107.             (labelType != labelPtr->labelType) && (!printOnly)) {
  108.         Disk_Label    *newLabelPtr;
  109.         status = Disk_EraseLabel(fid, labelPtr->labelType);
  110.         if (status != SUCCESS) {
  111.             printf("Couldn't erase old label.\n");
  112.             return status;
  113.         }
  114.         newLabelPtr = Disk_NewLabel(labelType);
  115.         newLabelPtr->numHeads = labelPtr->numHeads;
  116.         newLabelPtr->numSectors = labelPtr->numSectors;
  117.         newLabelPtr->numCylinders = labelPtr->numCylinders;
  118.         newLabelPtr->numAltCylinders = labelPtr->numAltCylinders;
  119.         bcopy(labelPtr->asciiLabel, newLabelPtr->asciiLabel, 
  120.             labelPtr->asciiLabelLen);
  121.         bcopy((char *) labelPtr->partitions, 
  122.               (char *) newLabelPtr->partitions,
  123.               sizeof(labelPtr->partitions));
  124.         labelPtr = newLabelPtr;
  125.         }
  126.     } else {
  127.         if (labelType == DISK_NO_LABEL) {
  128.         printf("Disk does not have a label. Use -labeltype\n");
  129.         return FAILURE;
  130.         }
  131.         labelPtr = Disk_NewLabel(labelType);
  132.         if (labelPtr == NULL) {
  133.         return FAILURE;
  134.         }
  135.     }
  136.     *labelPtrPtr = labelPtr;
  137.     }
  138.     if (disktab) {
  139.     status = ScanDisktab(disktabName, TRUE, diskType, labelPtr);
  140.     } else if (!scsiDisk) {
  141.     printf("You must specify the -configdisktab for a non-scsi disk.\n");
  142.     return FAILURE;
  143.     } else {
  144. #ifdef sprite
  145.     status = InventConfig(fid, labelPtr);
  146. #else
  147.     printf("You must use the -configdisktab option on unix.\n");
  148.     return FAILURE;
  149. #endif
  150.     }
  151.     if (status != SUCCESS) {
  152.     fprintf(stderr, "Unable to reconfigure disk\n");
  153.     } else {
  154.     int i;
  155.     /*
  156.      * Clear the partition map since we've changed the disk
  157.      * geometry.
  158.      */
  159.     for (i = 0; i < DISK_MAX_PARTS; i++) {
  160.         labelPtr->partitions[i].firstCylinder = 0;
  161.         labelPtr->partitions[i].numCylinders = 0;
  162.     }
  163.     }
  164.     return status;
  165. }
  166.  
  167. /*
  168.  *----------------------------------------------------------------------
  169.  *
  170.  * Repartition --
  171.  *
  172.  *    Repartitions the disk. If the disktab variable is TRUE then
  173.  *    all partitions are set from the disktab file, otherwise
  174.  *    a single partition is changed.
  175.  *
  176.  * Results:
  177.  *    SUCCESS if the partition map was changed properly, 
  178.  *    FAILURE otherwise
  179.  *
  180.  * Side effects:
  181.  *    The label on the disk is changed.
  182.  *
  183.  *----------------------------------------------------------------------
  184.  */
  185.  
  186. ReturnStatus
  187. Repartition(fid, disktab, disktabName, diskType, labelType, partition,
  188.     sizes, labelPtrPtr)
  189.     int            fid;        /* Handle for first partition of disk*/
  190.     Boolean        disktab;    /* TRUE => use disktab file. */
  191.     char        *disktabName;    /* Name of disktab file. */
  192.     char        *diskType;    /* Type of disk. */
  193.     Disk_NativeLabelType labelType;    /* Type of label to write. */
  194.     int            partition;    /* Which parition to change. */
  195.     int            *sizes;        /* Sizes of partitions as a pct.*/
  196.     Disk_Label        **labelPtrPtr;    /* Place to return label ptr. */
  197.  
  198. {
  199.    Disk_Label        *labelPtr = *labelPtrPtr;
  200.    ReturnStatus        status = SUCCESS;
  201.    int            adjust;
  202.  
  203.    if (labelPtr == NULL) {
  204.     labelPtr = Disk_ReadLabel(fid);
  205.     if (labelPtr != NULL) {
  206.         if ((labelType != DISK_NO_LABEL) && 
  207.             (labelType != labelPtr->labelType) && (!printOnly)) {
  208.         status = Disk_EraseLabel(fid, labelPtr->labelType);
  209.         if (status != SUCCESS) {
  210.             fprintf(stderr, "Can't erase disk label.\n");
  211.             return status;
  212.         }
  213.         labelPtr->labelType = labelType;
  214.         }
  215.     } else {
  216.         if (labelType == DISK_NO_LABEL) {
  217.         printf("Disk does not have a label. Use -labeltype\n");
  218.         return FAILURE;
  219.         }
  220.         labelPtr = Disk_NewLabel(labelType);
  221.         if (labelPtr == NULL) {
  222.         fprintf(stderr, "The disk does not have a label.\n");
  223.         return FAILURE;
  224.         }
  225.     }
  226.     *labelPtrPtr = labelPtr;
  227.     }
  228.     if (disktab) {
  229.     status = ScanDisktab(disktabName, FALSE, diskType, labelPtr);
  230.     } else {
  231.     int        firstCylinder;
  232.     int        numCylinders;
  233.     int        i;
  234.     Disk_Partition    *partitions = labelPtr->partitions;
  235.     for (i = 0; i < 7; i++) {
  236.         if (sizes[i] == 0) {
  237.         continue;
  238.         }
  239.         adjust = labelPtr->numCylinders * sizes[i] / 100;
  240.         /*
  241.          * Adjust the start and size of the current partition, and the
  242.          * start of all partitions that follow.
  243.          */
  244.         switch(i) {
  245.         case A_PART:
  246.             firstCylinder = 0;
  247.             partitions[B_PART].firstCylinder += adjust;
  248.             partitions[D_PART].firstCylinder += adjust;
  249.             partitions[E_PART].firstCylinder += adjust;
  250.             partitions[F_PART].firstCylinder += adjust;
  251.             partitions[G_PART].firstCylinder += adjust;
  252.             break;
  253.         case B_PART:
  254.             firstCylinder = partitions[A_PART].firstCylinder +
  255.                     partitions[A_PART].numCylinders;
  256.             partitions[D_PART].firstCylinder += adjust;
  257.             partitions[E_PART].firstCylinder += adjust;
  258.             partitions[F_PART].firstCylinder += adjust;
  259.             partitions[G_PART].firstCylinder += adjust;
  260.             break;
  261.         case C_PART:
  262.             firstCylinder = 0;
  263.             break;
  264.         case D_PART:
  265.             partitions[E_PART].firstCylinder += adjust;
  266.             partitions[F_PART].firstCylinder += adjust;
  267.         case G_PART:
  268.             firstCylinder = partitions[A_PART].firstCylinder +
  269.                     partitions[A_PART].numCylinders;
  270.             break;
  271.         case E_PART:
  272.             firstCylinder = partitions[D_PART].firstCylinder +
  273.                     partitions[D_PART].numCylinders;
  274.             partitions[F_PART].firstCylinder += adjust;
  275.             break;
  276.         case F_PART:
  277.             firstCylinder = partitions[E_PART].firstCylinder +
  278.                     partitions[E_PART].numCylinders;
  279.             break;
  280.         default:
  281.             fprintf(stderr, "Invalid partition %d\n", i);
  282.             return FAILURE;
  283.         }
  284.         partitions[i].firstCylinder = firstCylinder;
  285.         numCylinders = labelPtr->numCylinders * sizes[i] / 100;
  286.         partitions[i].numCylinders = numCylinders;
  287.     }
  288.     }
  289.     return status;
  290. }
  291.  
  292.  
  293. #define    BUF_SIZE    256
  294.  
  295. /*
  296.  *----------------------------------------------------------------------
  297.  *
  298.  * ScanDisktab --
  299.  *
  300.  *    Initialize the disk label by reading the information from
  301.  *     the disktab file.
  302.  *
  303.  * Results:
  304.  *    SUCCESS if the label was initialized properly, FAILURE otherwise
  305.  *
  306.  * Side effects:
  307.  *    None.
  308.  *
  309.  *----------------------------------------------------------------------
  310.  */
  311.  
  312. static ReturnStatus
  313. ScanDisktab(fileName, reconfig, diskType, labelPtr)
  314.     char    *fileName;    /* Name of the disktab file. */
  315.     Boolean    reconfig;    /* Reconfigure disk */
  316.     char    *diskType;    /* Type of disk. */
  317.     Disk_Label    *labelPtr;    /* The disk label. */
  318. {
  319.     char        buf[BUF_SIZE];
  320.     char        fullBuf[BUF_SIZE];
  321.     char        *bufPtr;
  322.     int            fullBufLen;
  323.     int            sectorsPerTrack;
  324.     int            tracksPerCylinder;
  325.     int            sectorsPerCylinder;
  326.     int            numCylinders;
  327.     FILE        *fp;
  328.     Disk_Partition      *partitions;
  329.     Disk_Partition      dummy[DISK_MAX_PARTS];
  330.     int            len;
  331.     int            i;
  332.  
  333.     if (diskType == NULL) {
  334.     printf(
  335.     "You must use the -disktype option when using the disktab file.\n");
  336.     return FAILURE;
  337.     }
  338.     fp = fopen(fileName, "r");
  339.     if (fp == NULL) {
  340.     fprintf(stderr,"Can't open %s", fileName);
  341.     exit(1);
  342.     }
  343.     len = strlen(diskType);
  344.     /*
  345.      * Scan until we reach a line that contains the disk type in it.
  346.      */
  347.     while (fgets(buf, BUF_SIZE, fp) != NULL) {
  348.     if (strncmp(diskType, buf, len) == 0 &&
  349.         buf[len] == '|') {
  350.         /*
  351.          * We found the disk type.
  352.          */
  353.         break;
  354.     }
  355.     }
  356.     if (strncmp(diskType, buf, len) != 0) {
  357.     fprintf(stderr, "`%s' not in disktab\n", diskType);
  358.     return FAILURE;
  359.     }
  360.  
  361.     fullBufLen = 0;
  362.     /*
  363.      * Now cram all of the lines that end in "\" together.
  364.      */
  365.     while (1) {
  366.     for (bufPtr = buf; 
  367.          *bufPtr != '\n' && *bufPtr != '\\' && (bufPtr - buf < sizeof(buf));
  368.          bufPtr++) {
  369.         if (*bufPtr != ' ' && *bufPtr != '\t') {
  370.         if (fullBufLen == sizeof(fullBuf)) {
  371.             break;
  372.         }
  373.         fullBuf[fullBufLen] = *bufPtr;
  374.         fullBufLen++;
  375.         }
  376.     }
  377.     if (bufPtr - buf == sizeof(buf) || fullBufLen == sizeof(fullBuf)) {
  378.         printf("Buffer overflow.\n");
  379.         return FAILURE;
  380.     }
  381.     if (*bufPtr == '\n') {
  382.         fullBuf[fullBufLen] = 0;
  383.         break;
  384.     }
  385.     if (fgets(buf, BUF_SIZE, fp) == NULL) {
  386.         fprintf(stderr, "Premature EOF\n");
  387.         exit(1);
  388.     }
  389.     }
  390.     if (reconfig) {
  391.     partitions = dummy;
  392.     } else {
  393.     partitions = labelPtr->partitions;
  394.     }
  395.     /*
  396.      * Now build up a partition table.
  397.      */
  398.     for (i = 0; i < DISK_MAX_PARTS; i++) {
  399.     partitions[i].firstCylinder = 0;
  400.     partitions[i].numCylinders = 0;
  401.     }
  402.     for (bufPtr = fullBuf; *bufPtr != 0; bufPtr++) {
  403.     int    partition;
  404.  
  405.     if (strncmp(bufPtr, ":ns#", 4) == 0) {
  406.         bufPtr += 4;
  407.         sscanf(bufPtr, "%d", §orsPerTrack);
  408.     } else if (strncmp(bufPtr, ":nt#", 4) == 0) {
  409.         bufPtr += 4;
  410.         sscanf(bufPtr, "%d", &tracksPerCylinder);
  411.     } else if (strncmp(bufPtr, ":nc#", 4) == 0) {
  412.         bufPtr += 4;
  413.         sscanf(bufPtr, "%d", &numCylinders);
  414.     } else if (strncmp(bufPtr, ":p", 2) == 0) {
  415.         /*
  416.          * Skip past the ":p".
  417.          */
  418.         bufPtr += 2;
  419.         partition = *bufPtr - 'a';
  420.         /*
  421.          * Skip past the partition character and the #.
  422.          */
  423.         bufPtr += 2;
  424.         sscanf(bufPtr, "%d", &partitions[partition].numCylinders);
  425.     }
  426.     }
  427.     if (reconfig) {
  428.     strcpy(labelPtr->asciiLabel, diskType);
  429.     labelPtr->numHeads = tracksPerCylinder;
  430.     labelPtr->numSectors = sectorsPerTrack;
  431.     labelPtr->numCylinders = numCylinders;
  432.     return SUCCESS;
  433.     } else {
  434.     tracksPerCylinder = labelPtr->numHeads;
  435.     sectorsPerTrack = labelPtr->numSectors;
  436.     numCylinders = labelPtr->numCylinders;
  437.     }
  438.     /*
  439.      * The partition sizes in the disktab file are in terms of sectors.
  440.      * Convert this to cylinders.
  441.      */
  442.     sectorsPerCylinder = sectorsPerTrack * tracksPerCylinder;
  443.     for (i = 0; i < FSDM_NUM_DISK_PARTS; i++) {
  444.     partitions[i].numCylinders /= sectorsPerCylinder;
  445.     }
  446.     /*
  447.      * Now that we've built up the number of cylinders build up the
  448.      * cylinder offsets.
  449.      */
  450.     partitions[A_PART].firstCylinder = 0;
  451.     partitions[B_PART].firstCylinder = partitions[A_PART].numCylinders;
  452.     partitions[C_PART].firstCylinder = 0;
  453.     partitions[D_PART].firstCylinder = partitions[B_PART].firstCylinder + 
  454.             partitions[B_PART].numCylinders;
  455.     partitions[E_PART].firstCylinder = partitions[D_PART].firstCylinder + 
  456.             partitions[D_PART].numCylinders;
  457.     partitions[F_PART].firstCylinder = partitions[E_PART].firstCylinder + 
  458.             partitions[E_PART].numCylinders;
  459.     partitions[F_PART].numCylinders = 
  460.             numCylinders - (partitions[E_PART].firstCylinder +
  461.                     partitions[E_PART].numCylinders);
  462.     partitions[G_PART].firstCylinder = partitions[B_PART].firstCylinder + 
  463.             partitions[B_PART].numCylinders;
  464.     partitions[G_PART].numCylinders = 
  465.             numCylinders - (partitions[B_PART].firstCylinder +
  466.                     partitions[B_PART].numCylinders);
  467.  
  468.     return SUCCESS;
  469. }
  470.  
  471. /*
  472.  *----------------------------------------------------------------------
  473.  *
  474.  * InventConfig --
  475.  *
  476.  *    Invents a configuration for the disk that maximizes the
  477.  *    amount of available space.  This only works if the disk
  478.  *    is a scsi disk.
  479.  *
  480.  * Results:
  481.  *    Pointer to the label.
  482.  *
  483.  * Side effects:
  484.  *    A scsi command is sent to the disk.
  485.  *
  486.  *----------------------------------------------------------------------
  487.  */
  488.  
  489. #ifdef sprite 
  490. ReturnStatus
  491. InventConfig(fid, labelPtr)
  492.     int        fid;        /* Handle on the raw disk. */
  493.     Disk_Label    *labelPtr;    /* The disk label. */
  494. {
  495.     ScsiCmd        cmd;        
  496.     CmdStatus        cmdStatus;
  497.     struct stat     statbuf;
  498.     int            numSectors;
  499.     int            size;
  500.     ReturnStatus    status = SUCCESS;
  501.     int            sectorsPerBlock;
  502.     int            lowerLimit;
  503.     int            upperLimit;
  504.     int            best;
  505.     int            leastWasted;
  506.     int            i;
  507.  
  508.     /*
  509.      * Send a Read Capacity SCSI command to the disk to find out how many
  510.      * sectors there are and how many bytes per sector.
  511.      */
  512.     bzero((char *) &cmd, sizeof(cmd));;
  513.     cmd.hdr.bufferLen = sizeof(ReadCapacityCommand);
  514.     cmd.hdr.commandLen = sizeof(ReadCapacityCommand);
  515.     cmd.hdr.dataOffset = sizeof(Dev_ScsiCommand)+sizeof(ReadCapacityCommand);
  516.     cmd.cmd.command = 0x25;
  517.     fstat(fid, &statbuf);
  518.     cmd.cmd.lun = (statbuf.st_rdev >> 7) & 0x7;
  519.     cmd.cmd.pmi = 0;
  520.     status = Fs_IOControl(fid, IOC_SCSI_COMMAND, cmd.hdr.dataOffset,
  521.             (char *) &cmd, sizeof(CmdStatus), (char *) &cmdStatus);
  522.     if (status != 0) {
  523.     fprintf(stderr,"Fs_IoControl returned status 0x%x : %s\n",status,
  524.             Stat_GetMsg(status));
  525.     exit(1);
  526.     }
  527.     numSectors = (cmdStatus.info.result.addr3 << 24 | 
  528.         cmdStatus.info.result.addr2 << 16 |
  529.         cmdStatus.info.result.addr1 << 8 |
  530.         cmdStatus.info.result.addr0) + 1;
  531.     size = cmdStatus.info.result.size3 << 24 | 
  532.         cmdStatus.info.result.size2 << 16 |
  533.         cmdStatus.info.result.size1 << 8 |
  534.         cmdStatus.info.result.size0;
  535.     if (size != 512) {
  536.     fprintf(stderr, "Whoa!  There are %d bytes in a sector!!!\n", size);
  537.     return FAILURE;
  538.     }
  539.     /*
  540.      * Now compute a "good" number of sectors per cylinder so that
  541.      * we waste as few as possible.  Remember that file system blocks
  542.      * cannot cross cylinder boundaries, and that the file system uses
  543.      * cylinders to localize the allocation of files. Therefore we
  544.      * don't want cylinders to be too big or too small. 
  545.      * I've arbitrarily
  546.      * chosen a lower limit of 16 blocks (64 K) and 
  547.      * picked an upper limit of 256 blocks (1 Mb).
  548.      * We also don't want too many cylinders since the filesystem
  549.      * does stuff on a cylinder basis.  The upper limit on the
  550.      * number of cylinders is 3000.
  551.      *
  552.      * The computation is brute force.  I don't know of a closed form
  553.      * solution.
  554.      */
  555.     sectorsPerBlock = FS_BLOCK_SIZE / size;
  556.     lowerLimit = sectorsPerBlock * 16;
  557.     upperLimit = sectorsPerBlock * 256;
  558.     if (numSectors / lowerLimit > 3000) {
  559.     lowerLimit = numSectors / 3000;
  560.     if (lowerLimit % sectorsPerBlock != 0) {
  561.         lowerLimit += sectorsPerBlock - (lowerLimit % sectorsPerBlock);
  562.     }
  563.     }
  564.     best = 0;
  565.     leastWasted = upperLimit;
  566.     /*
  567.      * Iterate over all sizes of cylinders such that a whole number
  568.      * of blocks fit in a cylinder.
  569.      */
  570.     for (i = lowerLimit; i <= upperLimit; i+=sectorsPerBlock) {
  571.     int left;
  572.  
  573.     /*
  574.      * Compute number of leftover sectors because the disk size
  575.      * is not a multiple of the cylinder size, and due to the
  576.      * one cylinder that we'll throw away at the start of the disk
  577.      * for the boot sectors and stuff.
  578.      */
  579.     left = numSectors % i + i;
  580.     if (left < leastWasted) {
  581.         leastWasted = left;
  582.         best = i;
  583.     }
  584.     }
  585.     labelPtr->numHeads = 1;
  586.     labelPtr->numSectors = best;
  587.     labelPtr->numCylinders = numSectors / best;
  588.     return status;
  589. }
  590. #endif
  591.  
  592.  
  593. /*
  594.  *----------------------------------------------------------------------
  595.  *
  596.  * ConfirmDiskSize --
  597.  *
  598.  *    Checks that the the last sector of the disk as computed from
  599.  *    the information in the label actually exists.
  600.  *
  601.  * Results:
  602.  *    SUCCESS if the sector can be read, FAILURE otherwise
  603.  *
  604.  * Side effects:
  605.  *    A sector is read from the disk.
  606.  *
  607.  *----------------------------------------------------------------------
  608.  */
  609.  
  610. ReturnStatus
  611. ConfirmDiskSize(fid, labelPtr, sizes)
  612.     int        fid;        /* Handle on the raw disk. */
  613.     Disk_Label    *labelPtr;    /* The disk label. */
  614.     int        *sizes;        /* Size of partitions. */
  615. {
  616.     int         lastSector;
  617.     int            status;
  618.     static char        buffer[DEV_BYTES_PER_SECTOR];
  619.     ReturnStatus    returnStatus = SUCCESS;
  620.     int            i;
  621.  
  622.     lastSector = labelPtr->numCylinders * labelPtr->numHeads *
  623.             labelPtr->numSectors - 1;
  624.     status = Disk_SectorRead(fid, lastSector, 1, buffer);
  625.     if (status != 0) {
  626.     fprintf(stderr, "Can't read last sector (%d) of disk.\n", lastSector);
  627.     fprintf(stderr, "Disk reconfiguration/repartition failed.\n");
  628.     return FAILURE;
  629.     }
  630.     for (i = 0; i < 7; i++) {
  631.     /*
  632.      * Ignore partitions we haven't modified.
  633.      */
  634.     if (sizes[i] == 0) {
  635.         continue;
  636.     }
  637.     lastSector = (labelPtr->partitions[i].firstCylinder  +
  638.              labelPtr->partitions[i].numCylinders) *
  639.              labelPtr->numHeads * labelPtr->numSectors - 1;
  640.     if (lastSector > 0) {
  641.         status = Disk_SectorRead(fid, lastSector, 1, buffer);
  642.         if (status != 0) {
  643.         fprintf(stderr, 
  644.             "Can't read last sector (%d) of the '%c' partition\n", 
  645.             lastSector, ((char) i) + 'a');
  646.         returnStatus = FAILURE;
  647.         }
  648.     }
  649.     }
  650.     return returnStatus;
  651. }
  652.  
  653. @
  654.  
  655.  
  656. 1.1
  657. log
  658. @Initial revision
  659. @
  660. text
  661. @d17 1
  662. a17 1
  663. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/proto.c,v 1.3 90/01/12 12:03:36 douglis Exp $ SPRITE (Berkeley)";
  664. d459 1
  665. d560 2
  666. a588 1
  667.     int         lastCyl;
  668. @
  669.